<template>
	<div class="blindness_model">
		<div class="blindness_model_all">
			<div class="countdown">
				<p class="countdown_p">
					<span class="countdown_p_span">倒计时：</span>
					<span class="countdown_p_span1">{{ time }}</span>
				</p>
				<p class="countdown_p">
					<span class="countdown_p_span">级别：</span>
					<span class="countdown_p_span1">{{ level }}</span>
				</p>
				<el-button
					class="home_reset"
					v-if="!isResult"
					:disabled="isBegin"
					@click="beginFun()"
					>开始</el-button
				>
				<el-button class="home_reset" v-else @click="resultFun()"
					>重置</el-button
				>
			</div>
			<canvas
				id="mycanvas"
				ref="mycanvas"
				:width="cnWidth"
				:height="cnWidth"
				@click="clickCanvasFun"
			></canvas>
		</div>
	</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { imgList } from "./../../../assets/image/juejin/index";
import {
	firstClass,
	secondClass,
	thirdClass,
	fourClass,
	fiveClass,
	sixClass,
	sevenClass,
	eightClass,
} from "./data";
const time = ref(60); // 颜色倒计时
const isBegin = ref(false); // 是否开始
const isResult = ref(false); // 是否显示重置
const timer = ref<any>(null); // 定时器
/**
 * @function 开始函数
 */
const beginFun = () => {
	isBegin.value = true;
	if (timer.value) {
		clearInterval(timer.value);
	}
	draw(); // 生成坐标
	timer.value = setInterval(() => {
		if (time.value < 1) {
			clearInterval(timer.value);
			deawBegin();
			isResult.value = true; // 显示重置按钮
		} else {
			time.value = time.value - 1;
		}
	}, 1000);
};
/**
 * @function 重置函数
 */
const resultFun = () => {
	isResult.value = false;
	time.value = 60; // 重置时间
	level.value = 1; // 重置难度
	nmbRow.value = 2;
	beginFun();
};
// 设置难度对应颜色列表和每一列个数
const colorList = [
	{
		row: 2, // 个数
		grade: 1, // 难度
		list: firstClass,
	},
	{
		row: 3,
		grade: 2,
		list: secondClass,
	},
	{
		row: 4,
		grade: 3,
		list: thirdClass,
	},
	{
		row: 5,
		grade: 4,
		list: fourClass,
	},
	{
		row: 6,
		grade: 6,
		list: fiveClass,
	},
	{
		row: 7,
		grade: 8,
		list: sixClass,
	},
	{
		row: 8,
		grade: 11,
		list: sevenClass,
	},
	{
		row: 9,
		grade: 17,
		list: eightClass,
	},
];
// 获取canvas
const mycanvas = ref(null);
// 生成canvas实例
let context = ref<any>(null);
// 当前难度级别
let level = ref(1);
// 当前每一列个数
let nmbRow = ref(2);
// 保存特殊颜色方块
let special = ref<any>({});
// canvas初始宽
let cnWidth = ref(0);
// 保存上次随机数
let randomLast = ref(0);
/**
 * @function 动态设置canvas宽高
 */
const setStyle = () => {
	let widthAll = document.documentElement.clientWidth;
	if (widthAll * 0.8 > 500) {
		cnWidth.value = 500;
	} else {
		cnWidth.value = widthAll;
	}
};
/**
 * @function 获取随机颜色
 * @param list 该等级颜色列表
 * @returns 当前难度设置的颜色
 */
const randomColor = (list: any) => {
	let length = list.length;
	let randNmb = makeRandom(length);
	// 避免出现重复颜色
	while (randomLast.value == randNmb) {
		randNmb = makeRandom(length);
	}
	randomLast.value = randNmb;
	return list[randNmb];
};
/**
 * @function 获取难度级别对应颜色集合
 * @param level 当前难度
 * @returns 当前难度对应的颜色集合
 */
const mappingFun = (level: number) => {
	let index = 0;
	let nmb = colorList.findIndex((item) => level < item.grade);
	if (nmb != -1) {
		index = nmb - 1;
	} else {
		index = colorList.length - 1;
	}
	return colorList[index].list;
};
/**
 * @function 计算绘制数量以及坐标
 * @param length 总宽度
 * @returns 绘制详情
 */
const countFun = (length: number) => {
	let onelength = length / nmbRow.value; // 每一个的宽度
	const randColoc = randomColor(mappingFun(level.value)); // 获取颜色
	const isColorX = makeRandom(nmbRow.value); // 特殊的颜色
	const isColorY = makeRandom(nmbRow.value); // 特殊的颜色
	const squareList = [];
	for (let i = 0; i < nmbRow.value; i++) {
		for (let j = 0; j < nmbRow.value; j++) {
			const obj = {
				x: j * onelength + 3,
				y: i * onelength + 3,
				width: onelength - 6,
				height: onelength - 6,
				color: "",
			};
			if (isColorX == j && isColorY == i) {
				obj.color = randColoc[1];
				special.value = obj; // 保存特殊颜色方块
			} else {
				obj.color = randColoc[0];
			}
			squareList.push(obj);
		}
	}
	return squareList;
};
/**
 * @function 绘制函数
 */
const draw = () => {
	const list = countFun(cnWidth.value); // 获取列表
	context.value.clearRect(0, 0, cnWidth.value, cnWidth.value);
	list.forEach((item) => {
		context.value.beginPath();
		context.value.fillStyle = item.color;
		context.value.fillRect(item.x, item.y, item.width, item.height);
		context.value.stroke();
		context.value.closePath(); // 结束绘制
	});
};
/**
 * @function 绑定点击事件
 */
const clickCanvasFun = (e: MouseEvent) => {
	if (!isBegin.value) return; // 没有开始不能点击
	const { offsetX, offsetY } = e; // 获取点击位置在画布的位置
	isInSpecial(offsetX, offsetY);
};
/**
 * @function 判断是否点击特殊颜色方块
 * @param offsetX 点击横坐标
 * @param offsetY 点击纵坐标
 */
const isInSpecial = (offsetX: number, offsetY: number) => {
	// 成立条件：
	// 1.点击纵坐标 > 特殊颜色起点的纵坐标
	// 2.点击横坐标 > 特殊颜色起点的横坐标
	// 3.点击纵坐标 - 特殊颜色起点的纵坐标 < 高度
	// 4.点击横坐标 - 特殊颜色起点的横坐标 < 宽度
	if (offsetY < special.value.y) return;
	if (offsetX < special.value.x) return;
	if (offsetX - special.value.x > special.value.width) return;
	if (offsetY - special.value.y > special.value.height) return;
	level.value = level.value + 1;
	let nmb = colorList.findIndex((item) => item.grade == level.value);
	if (nmb != -1) {
		nmbRow.value = colorList[nmb].row;
	}
	draw();
};
onMounted(() => {
	const c: any = mycanvas.value;
	context.value = c.getContext("2d");
	deawBegin();
});
/**
 * 绘制初始化界面
 */
const deawBegin = () => {
	context.value.clearRect(0, 0, cnWidth.value, cnWidth.value);
	let bgImg = new Image();
	bgImg.src = imgList[1];
	context.value.beginPath();
	bgImg.onload = function () {
		context.value.drawImage(bgImg, 0, 0, cnWidth.value, cnWidth.value);
	};
	context.value.closePath(); // 结束绘制
};
setStyle();
/**
 * @function 生成随机数
 * @param num 随机数区间
 * @returns 生成的随机数
 */
const makeRandom = (num: number) => {
	return Math.floor(Math.random() * num);
};
</script>
<style scoped lang="less">
.blindness_model {
	width: 100%;
	height: 100%;
	position: relative;
	background-color: rgb(149, 49, 52);
	.blindness_model_all {
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		.countdown {
			display: flex;
			align-items: center;
			.countdown_p {
				display: flex;
				align-items: center;
				margin-right: 30px;
				.countdown_p_span {
					font-size: 24px;
					font-family: Microsoft YaHei;
					font-weight: bold;
					color: #d5d5d5;
				}
				.countdown_p_span1 {
					font-size: 39px;
					font-family: Bahnschrift;
					font-weight: 400;
					color: #ffc05d;
				}
			}
			.home_reset {
				width: 20%;
			}
		}
		#mycanvas {
			cursor: pointer;
			background-color: #d5d5d5;
			padding: 10px;
		}
	}
}
</style>
